Skip to content

Conversation

HighPriest
Copy link

@HighPriest HighPriest commented Sep 18, 2025

  • [/] Format the code with prettier
  • [/] Make icons reflect possible interaction, instead of current state
    • Discuss with @semanticdata , which icons would be appropriate for the non-initiated state. It is a crossed out clock right now.
    • Logic being, that timer state should be extrapolated from the timer ticking, or not. The Icon does not need to say that. The icon should be there, to tell the user, what is going to happen on interaction.
  • Renamed variables to more appropriate values
  • Moved from manual timing to waiting for an epoch
  • Pause state managed by storing left-over duration in timer
  • Running state inferred from ticker interval being set
  • Start / Pause managed in single toggleTimer place (you either pause, or unpause. no in-between)
  • In persistentNotification mode, let the timer overflow
    • ?? Fix the negative sign position, when the timer overflows (don't use moment.abs(), it is broken. Doesn't just return the value, it overrides the object it is ran on...)
    • Add a test, which is going to check for a standardised format of the output text (both when it is positive and negative)
  • Make moment lib usable with jest
  • [/] Handle tests with new code
    • Fix issue with floating point precision of moment.duration().toISOString() (.seconds() has the same issue)
    • Fix issue with Obsidian Settings Mock, not having .addDropdown() available

Hello there @semanticdata
I had tried your plugin a few months ago and had in the back of my head, that I would like to see persistentNotifications in it. Hence, this PR.
I've got to say... the amount of tests in the code is ASTRONOMICAL. There are more tests than there is actual code 😅

I don't think it is something I am going to be able to figure out on my own. Help and suggestions would be greatly appreciated.

@HighPriest
Copy link
Author

I've adapted all the tests, so they are passing.
Some of them had really odd logic, which looked like they were made to always pass, no matter the actual application logic... So, all the tests, even those that are currently passing, should be looked through.


I am still seeing an error

TypeError: (intermediate value).setName(...).setDesc(...).addDropdown is not a function

      147 |                     .setName("Sound Selection")
      148 |                     .setDesc("Choose a built-in sound or select 'custom' to use your own.")
    > 149 |                     .addDropdown(dropdown => {
          |                      ^
      150 |                             const builtInSounds = this.soundManager.getBuiltInSounds();
      151 |                             builtInSounds.forEach(sound => {
      152 |                                     dropdown.addOption(sound, sound.replace('.wav', ''));

      at PomodoroSettingTab.display (src/components/SettingsTab.ts:149:5)
      at Object.<anonymous> (tests/settings-tab.test.ts:146:18)

which I would like to ask you, @semanticdata to correct. I don't know where to start looking.

- Renamed variables to more readable values
- Moved from manual timing to waiting for an epoch
- Pause state managed by storing left-over duration in timer
- running state inferred from ticker interval being set
- Start / Pause managed in single toggleTimer place (you either pause, or unpause. no in-between)
There are still issues with floating point precision
and "addDropdown" for some reason does not exist in Obsidian Settings mock
@HighPriest HighPriest force-pushed the persistentNotification branch from 64837d3 to 5db6309 Compare September 18, 2025 23:22
@semanticdata
Copy link
Owner

Hello, sorry I've been busy at work recently. I'll take a look at this as soon as I get a chance.

Thank you very much for taking the time to collaborate.

@semanticdata semanticdata self-assigned this Sep 23, 2025
@semanticdata semanticdata added bug Something isn't working enhancement New feature or request labels Sep 23, 2025
@HighPriest
Copy link
Author

HighPriest commented Sep 23, 2025

No pressure @semanticdata

I have been actually using the timer, with persistent notification & enjoyed it. Only issues being:

  • The first notification is often delayed, because the sound has to be pulled from CDN every time
  • There is no stats storage, which makes the app feel like it has no agency over me using it, or not. Making it forgetable.

There is still alot that can be done better. And, I am going to be gone from programming, for at least a month now. So, no pressure whatsoever.

@semanticdata
Copy link
Owner

Wanted to let you know I'm working on this today and should have some changes in a new branch for you to review and pull into your PR branch.

@semanticdata
Copy link
Owner

semanticdata commented Oct 15, 2025

Hello there @semanticdata I had tried your plugin a few months ago and had in the back of my head, that I would like to see persistentNotifications in it. Hence, this PR. I've got to say... the amount of tests in the code is ASTRONOMICAL. There are more tests than there is actual code 😅

I don't think it is something I am going to be able to figure out on my own. Help and suggestions would be greatly appreciated.

Hey, @HighPriest. I want to once again, thank you for taking the time to contribute to the plugin. I really appreciate it. Here's part of the checklist in your first post:

  • Make icons reflect possible interaction, instead of current state (I like the crossed out clock. 😄)
  • Fix the negative sign position, when the timer overflows
  • Add a test, which is going to check for a standardised format of the output text
  • Handle tests with new code
    • Fix issue with floating point precision
    • Fix issue with Obsidian Settings Mock

Here's a more detailed breakdown of the changes I made:

New settings migration logic was added to accommodate your renamed variables and keep the plugin backwards compatible. I also manually tested it by using old data and "updating" the plugin in development. Now there should be no settings loss for existing users. The migration happens automatically on first load after an update.

  • Add settings migration logic
    • Add settings migration test
    • Manually test settings migration

We are now using Math.floor() on integer milliseconds to eliminate floating point issues. The timer is now more accurate and no longer uses .minutes() or .seconds() methods. We don't use .toISOString() anymore.

  • Replace floating point operations with integer-based operations.
    • Fix isAtDefaultDuration() method.
    • Fix updateDisplay() method.
  • Fix timer overflow display (negative numbers)
    • Add positive time format test
    • Add negative time format test

I don't know if it's necessarily a bug, but behaviour that I didn't like. When the persistentNotification is enabled and the timer ends, a new notification appeared/disappeared every second. I changed it to stay persistent as a single one instead. The sound notification repeats every second stills, no changes there.

  • Separate persistent silent notification from sound notification
    • Persist silent notification until dismissed
    • Sound notification repeats every second until dismissed
  • Add proper cleanup to prevent notification leaks
  • Add new tests for the persistent notification
    • Add notification creation test
    • Add clear on pause/reset/toggle/cleanup tests

The Obsidian mock was improved substantially.

  • Implement .addDropdown() method in Obsidian mock
  • Implement remaining component mocks
    • Add addOption() mock
    • Add setValue() mock
    • Add onChange() mock
  • Centralize fake timer setup/teardown using beforeEach / afterEach
  • Minimize/eliminate risk of timer leaks between tests
  • Organize tests into describe blocks
  • Consolidate settings.test.ts into plugin.test.ts

Please review the feat/persistent-notification branch where I have committed the changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants